package cn.hwadee.muying.commons.mail.sender;

import cn.hwadee.muying.entity.Mail;
import cn.hwadee.muying.entity.MailMessage;
import cn.hwadee.muying.enums.MailSetting;
import com.sun.mail.smtp.SMTPSendFailedException;
import com.sun.mail.util.MailConnectException;
import com.sun.mail.util.MailSSLSocketFactory;
import org.apache.log4j.Logger;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.security.Security;
import java.util.Properties;

/**
 * @描述: 邮件接收器
 * @作者: Jing
 * @日期: 2018/1/26
 */
public class Sender {

    private static String PROTOCOL = "smtp";
    private static String TIME_OUT = "300000";  //5min
    private  final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    private Mail mail;
    private MailMessage mailMessage;
    private String host;
    private int retryTimes = 3;
    private Logger log = Logger.getLogger(Sender.class);

    public Sender(Mail _mail, MailMessage mailMessage){
        this.mail = _mail;
        MailSetting.setMailSettingBySmtp(mail);
        this.mailMessage = mailMessage;
        this.mail.setRecMailSetting(this.mail.getSendMailSetting());
        this.host=mail.getSendMailSetting().getSmtpHost();
    }

    public void send(String organization, String content) throws Exception{
        Properties props = new Properties();
        initProperties(props);
        Session session = Session.getInstance(props);
        MimeMessage mimeMessage = new MimeMessage(session);
        try {

            mimeMessage.setFrom(new InternetAddress(mail.getSendMail()));
            mimeMessage.addRecipients(Message.RecipientType.TO, mailMessage.getBuyerEmail());
            mimeMessage.setSubject("re:"+mailMessage.getSubject());
            //邮件正文
            Multipart multipart = new MimeMultipart();
            BodyPart bodyPart = new MimeBodyPart();
            bodyPart.setText(content);
            multipart.addBodyPart(bodyPart);
            mimeMessage.setSubject(organization,"UTF-8");
            mimeMessage.setContent(multipart);
            mimeMessage.saveChanges();

            //发送
            Transport transport = session.getTransport(PROTOCOL);
            transport.connect(host,mail.getSendMail(),mail.getSendMailAuthCode());
            transport.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
            transport.close();

        }catch (Exception e){
            if(e instanceof SMTPSendFailedException && e.getMessage().contains("554 DT:SPM")){
                retryTimes--;
                if(retryTimes > 0){
                    Thread.sleep(120000);
                    send(organization, content);
                }else{
                    throw new RuntimeException("邮件被退信，可能是邮件内容过于简单");
                }
            }
            if(e instanceof MailConnectException){
                retryTimes--;
                if(retryTimes > 0){
                    Thread.sleep(120000);
                    log.info(mail.getSendMail()+"连接不上发送邮件服务器，再次尝试连接服务器"+"host:"+mail.getRecMailSetting().getSmtpHost()
                            +"port:"+mail.getRecMailSetting().getSmtpPort());
                    send(organization,content);
                }else{
                    log.error("邮件发送失败，连接超时!",e);
                }
            }
            log.error("发送邮件异常:",e);
            e.printStackTrace();
            log.error("发送邮件出现错误，目标邮箱："+ mailMessage.getBuyerEmail()+"，卖家邮箱："+mail.getSendMail());
            throw new RuntimeException("发送邮件出现错误",e);
        }

    }


    public void initProperties(Properties props) throws Exception{
        props.setProperty("mail.store.protocol", mail.getSendMailSetting().getSmtpProtocol());
        props.setProperty("mail.smtp.auth","true");
        props.setProperty("mail.smtp.port", mail.getSendMailSetting().getSmtpPort());
        props.setProperty("mail.smtp.host", host);
        props.setProperty("mail.smtp.timeout", TIME_OUT);
        props.setProperty("mail.smtp.connectiontimeout",TIME_OUT);
        //使用ssl协议
        if(mail.getSendMailSetting().isSmtpIsSSL()){
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
            props.setProperty("mail.smtp.socketFactory.fallback", "true");
            String mailType=mail.getSendMail().substring(mail.getSendMail().indexOf("@")+1);
            if(mailType.equals("outlook.com")||mailType.equals("gmail.com")){//outlook,gmail邮箱协议加上startssl
                props.setProperty("mail.smtp.starttls.enable","true");
                props.setProperty("mail.smtp.socketFactory.port",mail.getSendMailSetting().getSmtpPort());
                MailSSLSocketFactory sf = new MailSSLSocketFactory();
                sf.setTrustAllHosts(true);
                props.put("mail.smtp.ssl.socketFactory", sf);
            }
        }
    }
}
